﻿using System;
using Rebazza.Server.Entities;
using Rebazza.Server.Interfaces;
using Rebazza.Server.Utils;
using Rebazza.Utils.Enums;

namespace Rebazza.Server.MessageHandlers
{
    public enum InternalType
    {
        Enter = 0,
        Exit = 1
    }

    public class RoomedMessage
    {
        public InternalType Type { get; set; }
        public int RoomNumber { get; set; }
    }

    public class RoomedHandler
    {
        public Message Handle(RoomedMessage message, IBaseGameServer gameServer, BaseUser user)
        {
            var roomedGameServer = gameServer as RoomedGameServer;
            if (roomedGameServer == null)
            {
                throw new ArgumentException("Casting GameServer to RoomedGameServer return null.");
            }

            switch (message.Type)
            {
                case InternalType.Enter:
                    return HandleEnter(message.RoomNumber, roomedGameServer, user);
                case InternalType.Exit:
                    return HandleExit(message.RoomNumber, roomedGameServer, user);
                default: return Messenger.GetErrorMessage(user.Context, "Bad command type.");
            }
        }

        private Message HandleEnter(int roomNumber, RoomedGameServer gameServer, IBaseUser user)
        {
            if (gameServer.TryEnterRoom(roomNumber, user))
            {
                return new Message
                           {
                               Mode = CommandMode.Base,
                               Type = CommandType.Roomed,
                               Command = new RoomedMessage
                                             {
                                                 Type = InternalType.Enter,
                                                 RoomNumber = roomNumber
                                             },
                               Status = CommandStatus.Success
                           };
            }

            return new Message
                       {
                           Mode = CommandMode.Base,
                           Type = CommandType.Roomed,
                           Command = new RoomedMessage
                                         {
                                             Type = InternalType.Enter,
                                             RoomNumber = roomNumber
                                         },
                           Status = CommandStatus.Error
                       };
        }

        private Message HandleExit(int roomNumber, RoomedGameServer gameServer, BaseUser user)
        {
            if (gameServer.TryExitRoom(roomNumber, user))
            {
                return new Message
                {
                    Mode = CommandMode.Base,
                    Type = CommandType.Roomed,
                    Command = new RoomedMessage
                    {
                        Type = InternalType.Exit,
                        RoomNumber = roomNumber
                    },
                    Status = CommandStatus.Success
                };
            }

            return new Message
            {
                Mode = CommandMode.Base,
                Type = CommandType.Roomed,
                Command = new RoomedMessage
                {
                    Type = InternalType.Exit,
                    RoomNumber = roomNumber
                },
                Status = CommandStatus.Error
            };
        }
    }
}
